home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / ov.cc < prev    next >
C/C++ Source or Header  |  1996-12-14  |  20KB  |  909 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include "Array-flags.h"
  32.  
  33. #include "ov.h"
  34. #include "ov-base.h"
  35. #include "ov-scalar.h"
  36. #include "ov-re-mat.h"
  37. #include "ov-complex.h"
  38. #include "ov-cx-mat.h"
  39. #include "ov-ch-mat.h"
  40. #include "ov-str-mat.h"
  41. #include "ov-range.h"
  42. #include "ov-struct.h"
  43. #include "ov-colon.h"
  44. #include "ov-va-args.h"
  45. #include "ov-typeinfo.h"
  46.  
  47. #include "defun.h"
  48. #include "gripes.h"
  49. #include "pager.h"
  50. #include "pr-output.h"
  51. #include "utils.h"
  52. #include "variables.h"
  53.  
  54. // We are likely to have a lot of octave_value objects to allocate, so
  55. // make the grow_size large.
  56. octave_allocator
  57. octave_value::allocator (sizeof (octave_value), 1024);
  58.  
  59. // If TRUE, allow assignments like
  60. //
  61. //   octave> A(1) = 3; A(2) = 5
  62. //
  63. // for A already defined and a matrix type.
  64. bool Vdo_fortran_indexing;
  65.  
  66. // Should we allow things like:
  67. //
  68. //   octave> 'abc' + 0
  69. //   97 98 99
  70. //
  71. // to happen?  A positive value means yes.  A negative value means
  72. // yes, but print a warning message.  Zero means it should be
  73. // considered an error.
  74. int Vimplicit_str_to_num_ok;
  75.  
  76. // Should we allow silent conversion of complex to real when a real
  77. // type is what we're really looking for?  A positive value means yes.
  78. // A negative value means yes, but print a warning message.  Zero
  79. // means it should be considered an error.
  80. int Vok_to_lose_imaginary_part;
  81.  
  82. // If TRUE, create column vectors when doing assignments like:
  83. //
  84. //   octave> A(1) = 3; A(2) = 5
  85. //
  86. // (for A undefined).  Only matters when resize_on_range_error is also
  87. // TRUE.
  88. bool Vprefer_column_vectors;
  89.  
  90. // If TRUE, prefer logical (zore-one) indexing over normal indexing
  91. // when there is a conflice.  For example, given a = [2, 3], the
  92. // expression  a ([1, 1]) would return [2 3] (instead of [2 2], which
  93. // would be returned if prefer_zero_one_indxing were FALSE).
  94. bool Vprefer_zero_one_indexing;
  95.  
  96. // If TRUE, print the name along with the value.
  97. bool Vprint_answer_id_name;
  98.  
  99. // Should operations on empty matrices return empty matrices or an
  100. // error?  A positive value means yes.  A negative value means yes,
  101. // but print a warning message.  Zero means it should be considered an
  102. // error.
  103. int Vpropagate_empty_matrices;
  104.  
  105. // If TRUE, resize matrices when performing and indexed assignment and
  106. // the indices are outside the current bounds.
  107. bool Vresize_on_range_error;
  108.  
  109. // How many levels of structure elements should we print?
  110. int Vstruct_levels_to_print;
  111.  
  112. // Allow divide by zero errors to be suppressed.
  113. bool Vwarn_divide_by_zero;
  114.  
  115. // Indentation level for structures.
  116. int struct_indent = 0;
  117.  
  118. // XXX FIXME XXX
  119. void
  120. increment_struct_indent (void)
  121. {
  122.   struct_indent += 2;
  123. }
  124.  
  125. void
  126. decrement_struct_indent (void)
  127. {
  128.   struct_indent -= 2;
  129. }
  130.  
  131. // Octave's value type.
  132.  
  133. string
  134. octave_value::binary_op_as_string (binary_op op)
  135. {
  136.   string retval;
  137.  
  138.   switch (op)
  139.     {
  140.     case add:
  141.       retval = "+";
  142.       break;
  143.  
  144.     case sub:
  145.       retval = "-";
  146.       break;
  147.  
  148.     case mul:
  149.       retval = "*";
  150.       break;
  151.  
  152.     case div:
  153.       retval = "/";
  154.       break;
  155.  
  156.     case pow:
  157.       retval = "^";
  158.       break;
  159.  
  160.     case ldiv:
  161.       retval = "\\";
  162.       break;
  163.  
  164.     case lt:
  165.       retval = "<";
  166.       break;
  167.  
  168.     case le:
  169.       retval = "<=";
  170.       break;
  171.  
  172.     case eq:
  173.       retval = "==";
  174.       break;
  175.  
  176.     case ge:
  177.       retval = ">=";
  178.       break;
  179.  
  180.     case gt:
  181.       retval = ">";
  182.       break;
  183.  
  184.     case ne:
  185.       retval = "!=";
  186.       break;
  187.  
  188.     case el_mul:
  189.       retval = ".*";
  190.       break;
  191.  
  192.     case el_div:
  193.       retval = "./";
  194.       break;
  195.  
  196.     case el_pow:
  197.       retval = ".^";
  198.       break;
  199.  
  200.     case el_ldiv:
  201.       retval = ".\\";
  202.       break;
  203.  
  204.     case el_and:
  205.       retval = "&";
  206.       break;
  207.  
  208.     case el_or:
  209.       retval = "|";
  210.       break;
  211.  
  212.     case struct_ref:
  213.       retval = ".";
  214.       break;
  215.  
  216.     default:
  217.       retval = "<unknown>";
  218.     }
  219.  
  220.   return retval;
  221. }
  222.  
  223. octave_value::octave_value (void)
  224.   : rep (new octave_base_value ()) { rep->count = 1; }
  225.  
  226. octave_value::octave_value (double d)
  227.   : rep (new octave_scalar (d)) { rep->count = 1; }
  228.  
  229. octave_value::octave_value (const Matrix& m)
  230.   : rep (new octave_matrix (m))
  231. {
  232.   rep->count = 1;
  233.   maybe_mutate ();
  234. }
  235.  
  236. octave_value::octave_value (const DiagMatrix& d)
  237.   : rep (new octave_matrix (d))
  238. {
  239.   rep->count = 1;
  240.   maybe_mutate ();
  241. }
  242.  
  243. octave_value::octave_value (const RowVector& v, int pcv)
  244.   : rep (new octave_matrix (v, pcv))
  245. {
  246.   rep->count = 1;
  247.   maybe_mutate ();
  248. }
  249.  
  250. octave_value::octave_value (const ColumnVector& v, int pcv)
  251.   : rep (new octave_matrix (v, pcv))
  252. {
  253.   rep->count = 1;
  254.   maybe_mutate ();
  255. }
  256.  
  257. octave_value::octave_value (const Complex& C)
  258.   : rep (new octave_complex (C))
  259. {
  260.   rep->count = 1;
  261.   maybe_mutate ();
  262. }
  263.  
  264. octave_value::octave_value (const ComplexMatrix& m)
  265.   : rep (new octave_complex_matrix (m))
  266. {
  267.   rep->count = 1;
  268.   maybe_mutate ();
  269. }
  270.  
  271. octave_value::octave_value (const ComplexDiagMatrix& d)
  272.   : rep (new octave_complex_matrix (d))
  273. {
  274.   rep->count = 1;
  275.   maybe_mutate ();
  276. }
  277.  
  278. octave_value::octave_value (const ComplexRowVector& v, int pcv)
  279.   : rep (new octave_complex_matrix (v, pcv))
  280. {
  281.   rep->count = 1;
  282.   maybe_mutate ();
  283. }
  284.  
  285. octave_value::octave_value (const ComplexColumnVector& v, int pcv)
  286.   : rep (new octave_complex_matrix (v, pcv))
  287. {
  288.   rep->count = 1;
  289.   maybe_mutate ();
  290. }
  291.  
  292. octave_value::octave_value (const char *s)
  293.   : rep (new octave_char_matrix_str (s))
  294. {
  295.   rep->count = 1;
  296.   maybe_mutate ();
  297. }
  298.  
  299. octave_value::octave_value (const string& s)
  300.   : rep (new octave_char_matrix_str (s))
  301. {
  302.   rep->count = 1;
  303.   maybe_mutate ();
  304. }
  305.  
  306. octave_value::octave_value (const string_vector& s)
  307.   : rep (new octave_char_matrix_str (s))
  308. {
  309.   rep->count = 1;
  310.   maybe_mutate ();
  311. }
  312.  
  313. octave_value::octave_value (const charMatrix& chm, bool is_string)
  314.   : rep (0)
  315. {
  316.   if (is_string)
  317.     rep = new octave_char_matrix_str (chm);
  318.   else
  319.     rep = new octave_char_matrix (chm);
  320.  
  321.   rep->count = 1;
  322.   maybe_mutate ();
  323. }
  324.  
  325. octave_value::octave_value (double base, double limit, double inc)
  326.   : rep (new octave_range (base, limit, inc))
  327. {
  328.   rep->count = 1;
  329.   maybe_mutate ();
  330. }
  331.  
  332. octave_value::octave_value (const Range& r)
  333.   : rep (new octave_range (r))
  334. {
  335.   rep->count = 1;
  336.   maybe_mutate ();
  337. }
  338.  
  339. octave_value::octave_value (const Octave_map& m)
  340.   : rep (new octave_struct (m)) { rep->count = 1; }
  341.  
  342. octave_value::octave_value (octave_value::magic_colon)
  343.   : rep (new octave_magic_colon ()) { rep->count = 1; }
  344.  
  345. octave_value::octave_value (octave_value::all_va_args)
  346.   : rep (new octave_all_va_args ()) { rep->count = 1; }
  347.  
  348. octave_value::octave_value (octave_value *new_rep)
  349.   : rep (new_rep) { rep->count = 1; }
  350.  
  351. octave_value::~octave_value (void)
  352. {
  353. #if defined (MDEBUG)
  354.   cerr << "~octave_value: rep: " << rep
  355.        << " rep->count: " << rep->count << "\n";
  356. #endif
  357.  
  358.   if (rep && --rep->count == 0)
  359.     {
  360.       delete rep;
  361.       rep = 0;
  362.     }
  363. }
  364.  
  365. void
  366. octave_value::maybe_mutate (void)
  367. {
  368.   octave_value *tmp = rep->try_narrowing_conversion ();
  369.  
  370.   if (tmp && tmp != rep)
  371.     {
  372.       if (--rep->count == 0)
  373.     delete rep;
  374.  
  375.       rep = tmp;
  376.       rep->count = 1;
  377.     }    
  378. }
  379.  
  380. static void
  381. gripe_no_conversion (const string& tn1, const string& tn2)
  382. {
  383.   error ("no suitable conversion found for assignment of %s to indexed %s",
  384.      tn2.c_str (), tn1.c_str ());
  385. }
  386.  
  387. octave_value&
  388. octave_value::assign (const octave_value_list& idx, const octave_value& rhs)
  389. {
  390.   make_unique ();
  391.  
  392.   bool assignment_ok = try_assignment (idx, rhs);
  393.  
  394.   if (! (error_state || assignment_ok))
  395.     {
  396.       assignment_ok = try_assignment_with_conversion (idx, rhs);
  397.  
  398.       if (! (error_state || assignment_ok))
  399.     gripe_no_conversion (type_name (), rhs.type_name ());
  400.     }
  401.  
  402.   if (! error_state)
  403.     maybe_mutate ();
  404.  
  405.   return *this;
  406. }
  407.  
  408. Octave_map
  409. octave_value::map_value (void) const
  410. {
  411.   return rep->map_value ();
  412. }
  413.  
  414. ColumnVector
  415. octave_value::vector_value (bool force_string_conv,
  416.                 bool force_vector_conversion) const
  417. {
  418.   ColumnVector retval;
  419.  
  420.   Matrix m = matrix_value (force_string_conv);
  421.  
  422.   if (error_state)
  423.     return retval;
  424.  
  425.   int nr = m.rows ();
  426.   int nc = m.columns ();
  427.  
  428.   if (nr == 1)
  429.     {
  430.       retval.resize (nc);
  431.       for (int i = 0; i < nc; i++)
  432.     retval (i) = m (0, i);
  433.     }
  434.   else if (nc == 1)
  435.     {
  436.       retval.resize (nr);
  437.       for (int i = 0; i < nr; i++)
  438.     retval (i) = m (i, 0);
  439.     }
  440.   else if (nr > 0 && nc > 0
  441.        && (Vdo_fortran_indexing || force_vector_conversion))
  442.     {
  443.       retval.resize (nr * nc);
  444.       int k = 0;
  445.       for (int j = 0; j < nc; j++)
  446.     for (int i = 0; i < nr; i++)
  447.       retval (k++) = m (i, j);
  448.     }
  449.   else
  450.     {
  451.       string tn = type_name ();
  452.       gripe_invalid_conversion (tn.c_str (), "real vector");
  453.     }
  454.  
  455.   return retval;
  456. }
  457.  
  458. ComplexColumnVector
  459. octave_value::complex_vector_value (bool force_string_conv,
  460.                     bool force_vector_conversion) const
  461. {
  462.   ComplexColumnVector retval;
  463.  
  464.   ComplexMatrix m = complex_matrix_value (force_string_conv);
  465.  
  466.   if (error_state)
  467.     return retval;
  468.  
  469.   int nr = m.rows ();
  470.   int nc = m.columns ();
  471.  
  472.   if (nr == 1)
  473.     {
  474.       retval.resize (nc);
  475.       for (int i = 0; i < nc; i++)
  476.     retval (i) = m (0, i);
  477.     }
  478.   else if (nc == 1)
  479.     {
  480.       retval.resize (nr);
  481.       for (int i = 0; i < nr; i++)
  482.     retval (i) = m (i, 0);
  483.     }
  484.   else if (nr > 0 && nc > 0
  485.        && (Vdo_fortran_indexing || force_vector_conversion))
  486.     {
  487.       retval.resize (nr * nc);
  488.       int k = 0;
  489.       for (int j = 0; j < nc; j++)
  490.     for (int i = 0; i < nr; i++)
  491.       retval (k++) = m (i, j);
  492.     }
  493.   else
  494.     {
  495.       string tn = type_name ();
  496.       gripe_invalid_conversion (tn.c_str (), "complex vector");
  497.     }
  498.  
  499.   return retval;
  500. }
  501.  
  502. void
  503. octave_value::print (bool pr_as_read_syntax)
  504. {
  505.   print (octave_stdout, pr_as_read_syntax);
  506. }
  507.  
  508. void
  509. octave_value::print_with_name (const string& name, bool print_padding)
  510. {
  511.   print_with_name (octave_stdout, name, print_padding);
  512. }
  513.  
  514. void
  515. octave_value::print_with_name (ostream& output_buf, const string& name,
  516.                    bool print_padding) 
  517. {
  518.   bool pad_after = false;
  519.  
  520.   if (Vprint_answer_id_name)
  521.     {
  522.       if (print_as_scalar ())
  523.     output_buf << name << " = ";
  524.       else if (is_map ())
  525.     {
  526.       pad_after = true;
  527.       output_buf << name << " =";
  528.     }
  529.       else
  530.     {
  531.       pad_after = true;
  532.       output_buf << name << " =\n\n";
  533.     }
  534.     }
  535.  
  536.   print (output_buf);
  537.  
  538.   if (print_padding && pad_after)
  539.     output_buf << "\n";
  540. }
  541.  
  542. bool
  543. octave_value::print_as_scalar (void)
  544. {
  545.   int nr = rows ();
  546.   int nc = columns ();
  547.  
  548.   return (is_scalar_type ()
  549.       || (is_string () && nr <= 1)
  550.       || (is_matrix_type ()
  551.           && ((nr == 1 && nc == 1)
  552.           || nr == 0
  553.           || nc == 0)));
  554. }
  555.  
  556. static void
  557. gripe_indexed_assignment (const string& tn1, const string& tn2)
  558. {
  559.   error ("assignment of %s to indexed %s not implemented",
  560.      tn2.c_str (), tn1.c_str ());
  561. }
  562.  
  563. static void
  564. gripe_conversion_failed (const string& tn1, const string& tn2)
  565. {
  566.   error ("type conversion for assignment of %s to indexed %s failed",
  567.      tn2.c_str (), tn1.c_str ());
  568. }
  569.  
  570. bool
  571. octave_value::convert_and_assign (const octave_value_list& idx,
  572.                   const octave_value& rhs)
  573. {
  574.   bool assignment_ok = false;
  575.  
  576.   int t_lhs = type_id ();
  577.   int t_rhs = rhs.type_id ();
  578.  
  579.   int t_result
  580.     = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
  581.  
  582.   if (t_result >= 0)
  583.     {
  584.       type_conv_fcn cf
  585.     = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
  586.  
  587.       if (cf)
  588.     {
  589.       octave_value *tmp = cf (*rep);
  590.  
  591.       if (tmp)
  592.         {
  593.           octave_value *old_rep = rep;
  594.           rep = tmp;
  595.           rep->count = 1;
  596.  
  597.           assignment_ok = try_assignment (idx, rhs);
  598.  
  599.           if (! assignment_ok && old_rep)
  600.           {
  601.             if (--rep->count == 0)
  602.               delete rep;
  603.  
  604.           rep = old_rep;
  605.           old_rep = 0;
  606.         }
  607.  
  608.           if (old_rep && --old_rep->count == 0)
  609.         delete old_rep;
  610.         }
  611.       else
  612.         gripe_conversion_failed (type_name (), rhs.type_name ());
  613.     }
  614.       else
  615.     gripe_indexed_assignment (type_name (), rhs.type_name ());
  616.     }
  617.  
  618.   return (assignment_ok && ! error_state);
  619. }
  620.  
  621. bool
  622. octave_value::try_assignment_with_conversion (const octave_value_list& idx,
  623.                           const octave_value& rhs)
  624. {
  625.   bool assignment_ok = convert_and_assign (idx, rhs);
  626.  
  627.   if (! (error_state || assignment_ok))
  628.     {
  629.       octave_value tmp_rhs;
  630.       type_conv_fcn cf_rhs = rhs.numeric_conversion_function ();
  631.  
  632.       if (cf_rhs)
  633.     tmp_rhs = octave_value (cf_rhs (*rhs.rep));
  634.       else
  635.     tmp_rhs = rhs;
  636.  
  637.       octave_value *old_rep = 0;
  638.       type_conv_fcn cf_this = numeric_conversion_function ();
  639.  
  640.       if (cf_this)
  641.     {
  642.       old_rep = rep;
  643.       rep = cf_this (*rep);
  644.       rep->count = 1;
  645.     }
  646.  
  647.       if (cf_this || cf_rhs)
  648.     {
  649.       assignment_ok = try_assignment (idx, tmp_rhs);
  650.  
  651.       if (! (error_state || assignment_ok))
  652.         assignment_ok = convert_and_assign (idx, tmp_rhs);
  653.     }
  654.  
  655.       if (! assignment_ok && old_rep)
  656.     {
  657.       if (--rep->count == 0)
  658.         delete rep;
  659.  
  660.       rep = old_rep;
  661.       old_rep = 0;
  662.     }
  663.  
  664.       if (old_rep && --old_rep->count == 0)
  665.     delete old_rep;
  666.     }
  667.  
  668.   return (assignment_ok && ! error_state);
  669. }
  670.  
  671. bool
  672. octave_value::try_assignment (const octave_value_list& idx,
  673.                   const octave_value& rhs)
  674. {
  675.   bool retval = false;
  676.  
  677.   int t_lhs = type_id ();
  678.   int t_rhs = rhs.type_id ();
  679.  
  680.   assign_op_fcn f = octave_value_typeinfo::lookup_assign_op (t_lhs, t_rhs);
  681.  
  682.   if (f)
  683.     {
  684.       f (*rep, idx, *(rhs.rep));
  685.  
  686.       retval = (! error_state);
  687.     }
  688.  
  689.   return retval;
  690. }
  691.  
  692. static void
  693. gripe_binary_op (const string& on, const string& tn1, const string& tn2)
  694. {
  695.   error ("binary operator %s not implemented for %s by %s operations",
  696.      on.c_str (), tn1.c_str (), tn2.c_str ());
  697. }
  698.  
  699. octave_value
  700. do_binary_op (octave_value::binary_op op, const octave_value& v1,
  701.           const octave_value& v2)
  702. {
  703.   octave_value retval;
  704.  
  705.   int t1 = v1.type_id ();
  706.   int t2 = v2.type_id ();
  707.  
  708.   binary_op_fcn f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
  709.  
  710.   if (f)
  711.     retval = f (*v1.rep, *v2.rep);
  712.   else
  713.     {
  714.       octave_value tv1;
  715.       type_conv_fcn cf1 = v1.numeric_conversion_function ();
  716.  
  717.       if (cf1)
  718.     {
  719.       tv1 = octave_value (cf1 (*v1.rep));
  720.       t1 = tv1.type_id ();
  721.     }
  722.       else
  723.     tv1 = v1;
  724.  
  725.       octave_value tv2;
  726.       type_conv_fcn cf2 = v2.numeric_conversion_function ();
  727.  
  728.       if (cf2)
  729.     {
  730.       tv2 = octave_value (cf2 (*v2.rep));
  731.       t2 = tv2.type_id ();
  732.     }
  733.       else
  734.     tv2 = v2;
  735.  
  736.       if (cf1 || cf2)
  737.     {
  738.       binary_op_fcn f
  739.         = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
  740.  
  741.       if (f)
  742.         retval = f (*tv1.rep, *tv2.rep);
  743.       else
  744.         gripe_binary_op (octave_value::binary_op_as_string (op),
  745.                  v1.type_name (), v2.type_name ());
  746.     }
  747.       else
  748.     gripe_binary_op (octave_value::binary_op_as_string (op),
  749.              v1.type_name (), v2.type_name ());
  750.     }
  751.  
  752.   return retval;
  753. }
  754.  
  755. void
  756. install_types (void)
  757. {
  758.   octave_base_value::register_type ();
  759.   octave_scalar::register_type ();
  760.   octave_complex::register_type ();
  761.   octave_matrix::register_type ();
  762.   octave_complex_matrix::register_type ();
  763.   octave_range::register_type ();
  764.   octave_char_matrix::register_type ();
  765.   octave_char_matrix_str::register_type ();
  766.   octave_struct::register_type ();
  767.   octave_all_va_args::register_type ();
  768.   octave_magic_colon::register_type ();
  769. }
  770.  
  771. static int
  772. do_fortran_indexing (void)
  773. {
  774.   Vdo_fortran_indexing = check_preference ("do_fortran_indexing");
  775.  
  776.   liboctave_dfi_flag = Vdo_fortran_indexing;
  777.  
  778.   return 0;
  779. }
  780.  
  781. static int
  782. implicit_str_to_num_ok (void)
  783. {
  784.   Vimplicit_str_to_num_ok = check_preference ("implicit_str_to_num_ok");
  785.  
  786.   return 0;
  787. }
  788.  
  789. static int
  790. ok_to_lose_imaginary_part (void)
  791. {
  792.   Vok_to_lose_imaginary_part = check_preference ("ok_to_lose_imaginary_part");
  793.  
  794.   return 0;
  795. }
  796.  
  797. static int
  798. prefer_column_vectors (void)
  799. {
  800.   Vprefer_column_vectors
  801.     = check_preference ("prefer_column_vectors");
  802.  
  803.   liboctave_pcv_flag = Vprefer_column_vectors;
  804.  
  805.   return 0;
  806. }
  807.  
  808. static int
  809. prefer_zero_one_indexing (void)
  810. {
  811.   Vprefer_zero_one_indexing = check_preference ("prefer_zero_one_indexing");
  812.  
  813.   liboctave_pzo_flag = Vprefer_zero_one_indexing;
  814.  
  815.   return 0;
  816. }
  817.  
  818. static int
  819. print_answer_id_name (void)
  820. {
  821.   Vprint_answer_id_name = check_preference ("print_answer_id_name");
  822.  
  823.   return 0;
  824. }
  825.  
  826. static int
  827. propagate_empty_matrices (void)
  828. {
  829.   Vpropagate_empty_matrices = check_preference ("propagate_empty_matrices");
  830.  
  831.   return 0;
  832. }
  833.  
  834. static int
  835. resize_on_range_error (void)
  836. {
  837.   Vresize_on_range_error = check_preference ("resize_on_range_error");
  838.  
  839.   liboctave_rre_flag = Vresize_on_range_error;
  840.  
  841.   return 0;
  842. }
  843.  
  844. static int
  845. struct_levels_to_print (void)
  846. {
  847.   double val;
  848.   if (builtin_real_scalar_variable ("struct_levels_to_print", val)
  849.       && ! xisnan (val))
  850.     {
  851.       int ival = NINT (val);
  852.       if (ival >= 0 && (double) ival == val)
  853.     {
  854.       Vstruct_levels_to_print = ival;
  855.       return 0;
  856.     }
  857.     }
  858.   gripe_invalid_value_specified ("struct_levels_to_print");
  859.   return -1;
  860. }
  861.  
  862. static int
  863. warn_divide_by_zero (void)
  864. {
  865.   Vwarn_divide_by_zero = check_preference ("warn_divide_by_zero");
  866.  
  867.   return 0;
  868. }
  869.  
  870. void
  871. symbols_of_value (void)
  872. {
  873.   DEFVAR (do_fortran_indexing, 0.0, 0, do_fortran_indexing,
  874.     "allow single indices for matrices");
  875.  
  876.   DEFVAR (implicit_str_to_num_ok, 0.0, 0, implicit_str_to_num_ok,
  877.     "allow implicit string to number conversion");
  878.  
  879.   DEFVAR (ok_to_lose_imaginary_part, "warn", 0, ok_to_lose_imaginary_part,
  880.     "silently convert from complex to real by dropping imaginary part");
  881.  
  882.   DEFVAR (prefer_column_vectors, 1.0, 0, prefer_column_vectors,
  883.     "prefer column/row vectors");
  884.  
  885.   DEFVAR (prefer_zero_one_indexing, 0.0, 0, prefer_zero_one_indexing,
  886.     "when there is a conflict, prefer zero-one style indexing");
  887.  
  888.   DEFVAR (print_answer_id_name, 1.0, 0, print_answer_id_name,
  889.     "set output style to print `var_name = ...'");
  890.  
  891.   DEFVAR (propagate_empty_matrices, 1.0, 0, propagate_empty_matrices,
  892.     "operations on empty matrices return an empty matrix, not an error");
  893.  
  894.   DEFVAR (resize_on_range_error, 1.0, 0, resize_on_range_error,
  895.     "enlarge matrices on assignment");
  896.  
  897.   DEFVAR (struct_levels_to_print, 2.0, 0, struct_levels_to_print,
  898.     "number of levels of structure elements to print");
  899.  
  900.   DEFVAR (warn_divide_by_zero, 1.0, 0, warn_divide_by_zero,
  901.     "If TRUE, warn about division by zero");
  902. }
  903.  
  904. /*
  905. ;;; Local Variables: ***
  906. ;;; mode: C++ ***
  907. ;;; End: ***
  908. */
  909.